Tengo este código con el que puedo verificar cuándo se alcanza la bottom de un div scrolling :
const checkBottomDiv = (el: HTMLElement) => { return el.getBoundingClientRect().bottom - 400 <= window.innerHeight; }; const contentArticleId = document.getElementById("myDiv") as HTMLElement; const trackScrolling = () => { callback(); if (checkBottomDiv(contentArticleId)) { console.log("bottomDiv"); document.removeEventListener("scroll", trackScrolling); } }; document.addEventListener("scroll", trackScrolling); Me gustaría reutilizar esta funcionalidad en otros components y, por este motivo, me gustaría poner esta lógica en una función separada y luego llamarla ( function.ts ).
Yo estoy haciendo esto:
app.tsx. //component useEffect(() => { let element = document.getElementById("myDiv") as HTMLElement; trackScrolling(element, callback); }) function.ts. //function file const checkBottomDiv = (el: HTMLElement) => { return el.getBoundingClientRect().bottom - 400 <= window.innerHeight; }; export const trackScrolling = (element: HTMLElement, callback: () => void) => { if (checkBottomDiv(element)) { callback(); document.removeEventListener("scroll", trackScrolling); } }; document.addEventListener("scroll", trackScrolling);pero me sale errores que no se como solucionar.
este es mi código en vivo:
https://codesandbox.io/s/epic-solomon-hu3e3
qué estoy haciendo mal y cómo puedo solucionarlo.
Aunque puedas, es posible que en realidad no quieras hacerlo de esta manera. Un mejor enfoque implicaría adjuntar el detector de eventos dentro del ciclo de vida del componenteDidMount o el enlace useEffect. Esto se traduce en el siguiente código:
const MyWrapperComponent = (props) => { useEffect(()=>{ document.addEventListener('scroll', (e)=>{ // do something }); return ()=>{ document.removeEventListener("scroll"); } },[]); }Pero dado que desea utilizar el evento de desplazamiento en muchos componentes, poner este enlace useEffect dentro de todos ellos espaguetirá su código, por lo que para evitar esto, puede utilizar la API de contexto para compartir los datos del evento con todos los componentes que lo necesitan. .
Tu document.addEventListener("scroll", trackScrolling); no está dentro de la función trackScrolling . Deberá mover eso dentro del cuerpo de la función para que tenga acceso a la callback de llamada. Su código debería verse así:
export const trackScrolling = (element: HTMLElement, callback: () => void) => { if (element && checkBottomDiv(element)) { callback(); document.removeEventListener("scroll", trackScrolling); } document.addEventListener("scroll", trackScrolling); }; Además, al escribir una funcionalidad personalizada para React como esta, si la lógica depende de un gancho (como useEffect ), puede ser más limpio incluir el gancho en la función personalizada también. Por ejemplo, es posible que desee algo más como esto:
app.tsx. //component useTrackScrolling("myDiv", callback); function.ts. //function file const checkBottomDiv = (el: HTMLElement) => { return el.getBoundingClientRect().bottom - 400 <= window.innerHeight; }; export const useTrackScrolling = (id: string, callback: () => void) => { const element = document.getElementById(id) as HTMLElement; useEffect(() => { const listener = () => { if (element && checkBottomDiv(element)) { callback(); document.removeEventListener("scroll", listener); } } document.addEventListener("scroll", listener); return () => document.removeEventListener("scroll", listener); }, [element, callback]); };Sin embargo, esa es solo mi opinión, puedes escribir tu código como prefieras :)